package com.ht.api.call.func.impl.task;

import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import com.ht.api.bean.AjaxResult;
import com.ht.api.bean.LoginBean;
import com.ht.api.call.func.IFunctionCall;
import com.ht.api.db.Db;
import com.ht.api.db.Entity;
import com.ht.api.db.exception.HtException;
import com.ht.api.db.task.HtTaskExecutor;
import com.ht.api.db.util.RedisUtil;

import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONObject;

/**
 * 查询任务组详情
 * @author asq
 * @createTime 2025年3月7日 15:38:13
 */
public class TaskGroupInfoFunctionCall implements IFunctionCall{

	@Override
	public String getName() {
		return "查询任务组详情";
	}

	@Override
	public JSONObject execute(LoginBean me, JSONObject param, AjaxResult result) {
		String groupId = param.getStr("group_id");
		if (StrUtil.isBlank(groupId)) {
			throw new HtException("group_id不能为空~");
		}
		
		// 先从缓存中查（如果任务组的任务未全部完成，此时缓存中的数据尚未存库）
		Entity entity = RedisUtil.hget(HtTaskExecutor.KEY_GROUP, groupId);
		if (entity == null) {
			entity = Db.createSqlParser("db_task_group").findById(groupId);
		}
		
		// 根据任务组的执行情况，计算一些附加字段
		if (entity != null) {
			// 计算任务组完成进度
			int total = entity.getInt("total");
			int done = entity.getInt("done");
			int progress = done * 100 / total;
			entity.set("progress", progress);
			
			// 如果已完成100%，则再统计失败的任务列表
			if (total == done) {
				setFailTaskListToEntity(entity, groupId);
			}
			
			// 去掉一些隐私字段
			entity.remove("table");
			entity.remove("callback");
			entity.remove("sys_deleted");
			entity.remove("sys_creator");
			entity.remove("param");
			
			return entity;
		} else {
			throw new HtException("group_id不存在：" + groupId);
		}
	}

	/**
	 * 为entity注入失败的任务列表信息
	 * @param entity
	 * @param groupId 任务组ID
	 */
	private void setFailTaskListToEntity(Entity entity, String groupId) {
		// 查询缓存中的失败任务数
		Map<Object, Object> mapTask = RedisUtil.entries(HtTaskExecutor.KEY_TASK);
		List<String> failTaskIdsByCache = mapTask.values().stream().map(t -> (Entity)t).filter(t -> {
			return groupId.equals(t.getStr("group_id")) && !"COMPLETED".equals(t.getStr("status"));
		}).map(t -> t.getMainId()).toList();
		
		// 查询数据库中的失败任务数
		List<Entity> failTasksByDb = Db.createSqlParser("db_task")
				.where("group_id", groupId).where("status", "FAILED").query();
		List<String> failTaskIdsByDb = failTasksByDb.stream().map(t -> t.getMainId()).toList();
		
		// 组装成一个大集合（去重）
		Set<String> failTaskIds = new HashSet<>();
		failTaskIds.addAll(failTaskIdsByCache);
		failTaskIds.addAll(failTaskIdsByDb);
		
		// 注入到entity中
		entity.set("fail_task_count", failTaskIds.size());
	}

}
